package cn.edu.njnu.opengmpback.resource.service.Impl;

import cn.edu.njnu.opengmpback.Modeling.dao.ComputeModelDao;
import cn.edu.njnu.opengmpback.Modeling.entity.ComputeModel;
import cn.edu.njnu.opengmpback.Modeling.utils.*;
import cn.edu.njnu.opengmpback.common.utils.*;
import cn.edu.njnu.opengmpback.resource.dao.*;
import cn.edu.njnu.opengmpback.resource.entity.*;
import cn.edu.njnu.opengmpback.resource.entity.dto.*;
import cn.edu.njnu.opengmpback.resource.service.ResCenterService;
import cn.edu.njnu.opengmpback.resource.dao.ModelItemDao;
import cn.edu.njnu.opengmpback.resource.entity.ModelItem;
import cn.edu.njnu.opengmpback.user.dao.UserDao;
import cn.edu.njnu.opengmpback.resource.entity.Param;
import cn.edu.njnu.opengmpback.user.entity.UserEntity;
import cn.edu.njnu.opengmpback.user.service.HistoryService;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;


@Slf4j
@Service
public class ResCenterServiceImpl implements ResCenterService {

    @Value("${dataStoreDir}"+"/resourceData")
    private  String resourceDataFolder;

    @Value("${dataStoreDir}")
    private  String dataStoreDir;

    @Value("${dataStoreDir}" + "/data")
    private  String dataDir;

    @Value("${tempUploadDir}")
    String tempUploadDir;

    @Value("${portalLocation}")
    String portalLocation;

    @Value("${dataServerLocation}")
    String dataServerLocation;

    @Autowired
    ResourceDataDao resourceDataDao;

    @Autowired
    ResourceSmallFileDao resourceSmallFileDao ;

    @Autowired
    FolderDao folderDao ;

    @Autowired
    UserDataDao userDataDao;

    @Autowired
    UserDao userDao;

    @Autowired
    CommonService commonService;

    @Autowired
    ModelItemDao modelItemDao;

    @Autowired
    HistoryService historyService;

    @Autowired
    PortalModelDao portalModelDao;
    @Autowired
    private ComputeModelDao computeModelDao;


    public JsonResult saveResourceData(CreateResourceDataDTO createResourceDataDTO, MultipartFile visualFile/*, MultipartFile imgFile*/) {
        try{
            File folder = new File(resourceDataFolder);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }

            ResourceData resourceData= new ResourceData();
            BeanUtils.copyProperties(createResourceDataDTO,resourceData);

            //大文件
            String srcFilePath=tempUploadDir+createResourceDataDTO.getFileStoreName();
            FileUtil.copy(srcFilePath,resourceDataFolder,true);
            FileUtil.del(srcFilePath); //删除大文件临时存在的位置

            SubDataItem DataItem = new SubDataItem();

            String name = createResourceDataDTO.getFileStoreName();
            DataItem.setName(name);
            DataItem.setType(name.substring(name.lastIndexOf(".") + 1));
            DataItem.setSize(resourceData.getFileSize());
            DataItem.setFileStoreName(resourceData.getFileStoreName());
            DataItem.setFileWebAddress(resourceData.getFileWebAddress());
            DataItem.setProblemTags(resourceData.getProblemTags());
            DataItem.setNormalTags(resourceData.getNormalTags());
            DataItem.setUserId(resourceData.getUserEmail());
            DataItem.setVisualWebAddress("/store/resourceData/"+createResourceDataDTO.getFileStoreName());
            DataItem.setPublicBoolean(true);
            DataItem.setFileRelativePath("/resourceData/"+createResourceDataDTO.getFileStoreName());

            ArrayList<SubDataItem> subDataItems = resourceData.getSubDataItems();

            if(createResourceDataDTO.getFileStoreName().endsWith(".zip")){
                List<JSONObject> fileInfo;
                try {
                    fileInfo = FileUtils.zipUncompress(
                            resourceDataFolder+"/"+createResourceDataDTO.getFileStoreName(),
                            resourceDataFolder+"/"+createResourceDataDTO.getFileStoreName().split(".zip")[0]);
                } catch (Exception e) {
                    return null;
                }
                for (JSONObject item : fileInfo) {
                    String fileName = item.getString("fileName");
                    SubDataItem subDataItem = new SubDataItem();
                    String path = item.getString("path");
                    Long fileSize = item.getLong("fileSize");
                    subDataItem.setName(fileName);
                    subDataItem.setType(fileName.substring(fileName.lastIndexOf(".") + 1));
                    subDataItem.setSize(fileSize.toString());
                    subDataItem.setFileStoreName(resourceData.getFileStoreName());
                    subDataItem.setFileWebAddress(resourceData.getFileWebAddress());
                    subDataItem.setProblemTags(resourceData.getProblemTags());
                    subDataItem.setNormalTags(resourceData.getNormalTags());
                    subDataItem.setUserId(resourceData.getUserEmail());
                    subDataItem.setVisualWebAddress("");
                    subDataItem.setPublicBoolean(true);
                    subDataItem.setFileRelativePath(path.split(dataStoreDir)[1]);
                    subDataItems.add(subDataItem);
                }
                //解压成功后把压缩包给删了
                FileUtils.deleteZIP(resourceDataFolder+"/"+createResourceDataDTO.getFileStoreName());
            }
            else subDataItems.add(DataItem);
            resourceData.setSubDataItems(subDataItems);

            //图像
//            if (imgFile.isEmpty()) {
//                resourceData.setImgWebAddress("");
//            }else {
//                //将文件保存到指定位置
//                String imgFileName = imgFile.getOriginalFilename(); //eg: XXX.js
//                String imgFileMainName= FileNameUtil.mainName(imgFileName); // XXX
//                String imgFileExtName = FileNameUtil.extName(imgFileName); //js
//                String imgFileNewName= IdUtil.objectId()+"."+imgFileExtName;
//                File saveImgFile = new File(folder, imgFileNewName);//eg: E:\\TEMP\\1231231.js
//                imgFile.transferTo(saveImgFile);
//                resourceData.setImgStoreName(imgFileNewName);
//                resourceData.setImgWebAddress("/store/resourceData/"+imgFileNewName);
//                resourceData.setImgRelativePath("/resourceData/"+imgFileNewName);
//            }
            resourceData.setUserEmail("opengms@126.com"); // todo: 将数据创建者设置为真正的数据创建者
            resourceDataDao.save(resourceData);

            return ResultUtils.success(resourceData);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"保存资源数据失败！");
        }
    }

    public JsonResult getResourceDataList(ResourcePageDTO resourcePageDTO) {
        try{
            Pageable pageable = commonService.getResourcePageable(resourcePageDTO);
            String tagClass= resourcePageDTO.getTagClass();

            if(tagClass.equals("problemTags")){
                Page<ResourceData> re = resourceDataDao.findAllByNameLikeIgnoreCaseAndProblemTagsLikeIgnoreCase(resourcePageDTO.getSearchText(), resourcePageDTO.getTagName(),pageable);
                return ResultUtils.success(re);
            }else if(tagClass.equals("normalTags")){
                Page<ResourceData> re = resourceDataDao.findAllByNameLikeIgnoreCaseAndNormalTagsLikeIgnoreCase(resourcePageDTO.getSearchText(), resourcePageDTO.getTagName(),pageable);
                return ResultUtils.success(re);
            }else {
                return ResultUtils.error(-1,"数据类别不正确，problemTags或normalTags");
            }
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"获取资源数据失败！");
        }
    }

    public JsonResult deleteResourceData(String resourceDataId) {
        try{
            ResourceData resourceData = resourceDataDao.findById(resourceDataId).get();

            String filePath=resourceDataFolder+"/"+resourceData.getFileStoreName();
            FileUtil.del(filePath);

            ArrayList<SubDataItem> subDataItems = resourceData.getSubDataItems();
            for(SubDataItem item : subDataItems){
                String visualFilePath=resourceDataFolder+"/"+item.getVisualStoreName();
                FileUtil.del(visualFilePath);
            }

            String imgFilePath=resourceDataFolder+"/"+resourceData.getImgStoreName();
            FileUtil.del(imgFilePath);

            resourceDataDao.deleteById(resourceDataId);
            return ResultUtils.success("删除资源数据成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"删除资源数据失败！");
        }
    }

    public JsonResult saveResourceSmallFile(CreateResourceSmallFileDTO createResourceSmallFileDTO, MultipartFile upSmallFile) {
        try{
            File folder = new File(resourceDataFolder);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }

            ResourceSmallFile resourceSmallFile=new ResourceSmallFile();
            BeanUtils.copyProperties(createResourceSmallFileDTO,resourceSmallFile);

            //可视化文件
            if (upSmallFile.isEmpty()) {
                return ResultUtils.error(-1,"上传文件为空");
            }

            //将文件保存到指定位置
            String fileName = upSmallFile.getOriginalFilename(); //eg: XXX.js
            String fileMainName= FileNameUtil.mainName(fileName); // XXX
            String fileExtName = FileNameUtil.extName(fileName); //js
            String fileNewName=IdUtil.objectId()+"."+fileExtName;
            File saveVisualFile = new File(folder, fileNewName);//eg: E:\\TEMP\\1231231.js

            upSmallFile.transferTo(saveVisualFile);
            resourceSmallFile.setFileStoreName(fileNewName);
            resourceSmallFile.setFileWebAddress("/store/resourceData/"+fileNewName);

            resourceSmallFile.setUserEmail("temp@xx.com");
            resourceSmallFileDao.save(resourceSmallFile);

            return ResultUtils.success("保存资源小文件成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"保存资源小文件失败！");
        }
    }

    public JsonResult saveResourceItemFile(CreateResourceSmallFileDTO createResourceSmallFileDTO, MultipartFile upSmallFile) {
        try{
            File folder = new File(resourceDataFolder);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }

            ResourceData resourceItemFile=new ResourceData();
            BeanUtils.copyProperties(createResourceSmallFileDTO,resourceItemFile);

            //可视化文件
            if (upSmallFile.isEmpty()) {
                return ResultUtils.error(-1,"上传文件为空");
            }

            //将文件保存到指定位置
            String fileName = upSmallFile.getOriginalFilename(); //eg: XXX.js
            String fileMainName= FileNameUtil.mainName(fileName); // XXX
            String fileExtName = FileNameUtil.extName(fileName); //js
            String fileNewName=IdUtil.objectId()+"."+fileExtName;
            File saveVisualFile = new File(folder, fileNewName);//eg: E:\\TEMP\\1231231.js

            upSmallFile.transferTo(saveVisualFile);
            resourceItemFile.setImgStoreName(fileNewName);
            resourceItemFile.setImgWebAddress("/store/resourceData/"+fileNewName);
            resourceItemFile.setImgRelativePath("/resourceData/"+fileNewName);
            resourceItemFile.setFileSize("0");
            resourceItemFile.setUserEmail("temp@xx.com");
            resourceDataDao.save(resourceItemFile);

            return ResultUtils.success("保存资源条目数据成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"保存资源条目数据失败！");
        }
    }

    public JsonResult deleteResourceSmallFile(String resourceSmallFileId) {
        try{

            ResourceSmallFile resourceSmallFile=resourceSmallFileDao.findById(resourceSmallFileId).get();

            String filePath=resourceDataFolder+"/"+resourceSmallFile.getFileStoreName();
            FileUtil.del(filePath);

            resourceDataDao.deleteById(resourceSmallFileId);
            return ResultUtils.success("删除资源小文件成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"删除资源小文件失败！");
        }
    }

    public JsonResult createResourceModel(CreateResourceModelDTO createResourceModelDTO, MultipartFile imgFile) {
        try{
            File folder = new File(resourceDataFolder);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }

            ModelItem modelItem =new ModelItem();
            BeanUtils.copyProperties(createResourceModelDTO, modelItem);

            modelItem.setMdlJson(ModelUtils.convertMdl(createResourceModelDTO.getMdl()));

            //图像
            if (imgFile.isEmpty()) {
                modelItem.setImgWebAddress("");
            }else {
                //将文件保存到指定位置
                String imgFileName = imgFile.getOriginalFilename(); //eg: XXX.js
                String imgFileMainName= FileNameUtil.mainName(imgFileName); // XXX
                String imgFileExtName = FileNameUtil.extName(imgFileName); //js
                String imgFileNewName=IdUtil.objectId()+"."+imgFileExtName;
                File saveImgFile = new File(folder, imgFileNewName);//eg: E:\\TEMP\\1231231.js
                imgFile.transferTo(saveImgFile);
                modelItem.setImgStoreName(imgFileNewName);
                modelItem.setImgWebAddress("/store/resourceData/"+imgFileNewName);
                modelItem.setImgRelativePath("/resourceData/"+imgFileNewName);
            }

            modelItemDao.save(modelItem);

            return ResultUtils.success("创建模型条目成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"创建模型条目失败！");
        }
    }

    public JsonResult deleteResourceModel(String resourceModelId) {
        try{
            modelItemDao.deleteById(resourceModelId);
            return ResultUtils.success("删除模型条目成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"删除模型条目失败！");
        }
    }

    @Override
    public JsonResult createResourceMethod(CreateResourceMethodDTO createResourceMethodDTO, MultipartFile imgFile) {
        try{
            File folder = new File(resourceDataFolder);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }

            ModelItem modelItem =new ModelItem();
            BeanUtils.copyProperties(createResourceMethodDTO, modelItem);

            //图像
            if (imgFile.isEmpty()) {
                modelItem.setImgWebAddress("");
            }else {
                //将文件保存到指定位置
                String imgFileName = imgFile.getOriginalFilename(); //eg: XXX.js
                String imgFileMainName= FileNameUtil.mainName(imgFileName); // XXX
                String imgFileExtName = FileNameUtil.extName(imgFileName); //js
                String imgFileNewName=IdUtil.objectId()+"."+imgFileExtName;
                File saveImgFile = new File(folder, imgFileNewName);//eg: E:\\TEMP\\1231231.js
                imgFile.transferTo(saveImgFile);
                modelItem.setImgStoreName(imgFileNewName);
                modelItem.setImgWebAddress("/store/resourceData/"+imgFileNewName);
                modelItem.setImgRelativePath("/resourceData/"+imgFileNewName);
            }

            modelItemDao.save(modelItem);

            return ResultUtils.success("创建模型条目成功！");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"创建模型条目失败！");
        }
    }

    @Override
    public JsonResult getResourceMethodList(ResourcePageDTO resourcePageDTO) {
        try{
            Pageable pageable = commonService.getResourcePageable(resourcePageDTO);
            Page<ModelItem> re = modelItemDao.findAllByModelTypeAndNameLikeIgnoreCaseAndNormalTagsContainingIgnoreCase("method",resourcePageDTO.getSearchText(), resourcePageDTO.getTagNames(),pageable);
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"获取数据方法失败！");
        }
    }

    @Override
    public JsonResult saveModeltoUserSpace(String id, String userId) {
        try {
            UserEntity user = userDao.findByUserId(userId);
            user.getToolList().add(id);
            userDao.save(user);
            return ResultUtils.success("保存工具成功");

        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"保存工具失败");
        }
    }
    // 获取每页的健康的模型
    private  OnePageMd5 getHealthyModelMd5(int page, int pageSize) {
        List<String> md5List = new ArrayList<>();
        Integer total = null;
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://" + portalLocation +"/managementSystem/deployedModel?ua6R2Qbf=0cvx_0alqEHJRFRaPfczQAGVL6obCzYn1J2tWiQZKc0MD9oss1d3YEE6a21Ollu8xNEo9b1mV4EBJzlX08xQswyK2OTcOsAiQ";
        JSONObject body = new JSONObject();
        body.put("asc", false);
        body.put("page", page);
        body.put("pageSize", pageSize);
        body.put("searchText", "");
        body.put("sortField", "viewCount");
        // 发送 GET 请求并接收 ResponseEntity
//        return restTemplate.postForEntity(url, body, String.class);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, body, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            String responseBody = responseEntity.getBody();
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                JsonNode bodyNode = objectMapper.readTree(responseBody);
                JsonNode dataNode = bodyNode.get("data");
                total = dataNode.get("total").asInt();
                JsonNode content = dataNode.get("content");
                if (content.isArray()) {
                    for (int i = 0; i < content.size(); i++) {
                        JsonNode itemNode = content.get(i);
                        md5List.add(itemNode.get("md5").asText());
                    }
                }
            } catch (Exception e) {
//                    e.printStackTrace();
                log.error(e.getMessage());
            }
        }
        return new OnePageMd5(total, md5List);
    }
//    获取所有健康的模型的md5
    private List<String> getPortalModelsMd5() {
        OnePageMd5 onePageMd5 = getHealthyModelMd5(1, 20);
        List<String> modelsMd5List = new ArrayList<>(onePageMd5.getMd5List());
        Integer totalModels = onePageMd5.getTotal();
        Integer totalPage = (int) Math.ceil((double) totalModels / 20);
        for (int i = 2; i <= totalPage; i++) {
            onePageMd5 = getHealthyModelMd5(i, 20);
            modelsMd5List.addAll(onePageMd5.getMd5List());
        }
        return modelsMd5List;
    }
    // mdlJson解析方法
    private ModelItemEventData getModelItemEventData(JsonNode dataArr) {
        ModelItemEventData eventData = new ModelItemEventData();
        if (dataArr == null) return null;
        if (dataArr.isArray()) {
            JsonNode data = dataArr.get(0);
            eventData.setEventDataType(data.get("dataType").asText());
            eventData.setEventDataText(data.get("text").asText());
            eventData.setEventDataDesc(data.get("desc").asText());

            JsonNode nodes = data.get("nodes");
            if (nodes != null) {
                List<ModelItemEventDataNode> nodeList = new ArrayList<>();
                for (JsonNode node : nodes) {
                    ModelItemEventDataNode modelItemEventDataNode = new ModelItemEventDataNode();
                    modelItemEventDataNode.setText(node.get("text").asText());
                    modelItemEventDataNode.setDescription(node.get("desc").asText());
                    modelItemEventDataNode.setDataType(node.get("dataType").asText());
                    nodeList.add(modelItemEventDataNode);
                }
                eventData.setNodeList(nodeList);
            }
        }

        return eventData;
    }
    private ModelItemEvent getModelItemEvent(JsonNode event) {
        ModelItemEvent modelItemEvent = new ModelItemEvent();
        modelItemEvent.setEventName(event.get("eventName").asText());
        modelItemEvent.setEventDescription(event.get("eventDesc").asText());
//        modelItemEvent.setOptional(event.get("optional").asBoolean());
        // 检查event是否有optional字段，且该字段不为null
        if (event.has("optional") && !event.get("optional").isNull()) {
            // 如果存在，使用asBoolean()获取boolean值
            modelItemEvent.setOptional(event.get("optional").asBoolean());
        } else {
            // 如果event为null或者没有optional字段，或者optional字段为null，设置为false
            modelItemEvent.setOptional(false);
        }
        modelItemEvent.setEventType(event.get("eventType").asText());
        modelItemEvent.setEventData(getModelItemEventData(event.get("data")));
        return modelItemEvent;
    }
    private Map<String, ModelItemState> getModelItemState(JsonNode state) {
        String stateName = state.get("name").asText();
        String stateDesc = state.get("desc").asText();

        ModelItemState inputState = new ModelItemState();
        inputState.setStateName(stateName);
        inputState.setStateDescription(stateDesc);
        ModelItemState outputState = new ModelItemState();
        outputState.setStateName(stateName);
        outputState.setStateDescription(stateDesc);

        List<ModelItemEvent> inputEvents = new ArrayList<>();
        List<ModelItemEvent> outputEvents = new ArrayList<>();
        JsonNode events = state.get("event");
        for (JsonNode event : events) {
            ModelItemEvent modelItemEvent = getModelItemEvent(event);
            assert modelItemEvent != null;
            if (Objects.equals(modelItemEvent.getEventType(), "response")) {
                inputEvents.add(modelItemEvent);
            } else {
                outputEvents.add(modelItemEvent);
            }
        }
        inputState.setEvents(inputEvents);
        outputState.setEvents(outputEvents);

        Map<String, ModelItemState> map = new HashMap<>();
        map.put("input", inputState);
        map.put("output", outputState);
        return map;
    }
    private ModelItemData getModelItemData(JsonNode states) {
        ModelItemData modelItemData = new ModelItemData();
        List<ModelItemState> input = new ArrayList<>();//输入数据
        List<ModelItemState> output = new ArrayList<>();//输出数据
        for (JsonNode state : states) {
            Map<String, ModelItemState> map = getModelItemState(state);
            input.add(map.get("input"));
            output.add(map.get("output"));
        }
        modelItemData.setInput(input);
        modelItemData.setOutput(output);
        return modelItemData;
    }

    @Override
    public JsonResult getFromPortalModel() {
        List<String> modelsMd5List = getPortalModelsMd5();
        String baseUrl = "http://" + portalLocation + "/computableModel/ModelInfoAndClassifications_pid/";
        RestTemplate restTemplate = new RestTemplate();
        for (String modelMd5 : modelsMd5List) {
            ResponseEntity<String> responseEntity;
            try {
                responseEntity = restTemplate.getForEntity(baseUrl + modelMd5 , String.class);
            }
            catch (Exception e) {
                log.error(e.getMessage());
                continue;
            }
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                String responseBody = responseEntity.getBody();
                ObjectMapper objectMapper = new ObjectMapper();
                try {
                    JsonNode bodyNode = objectMapper.readTree(responseBody);
                    JsonNode dataNode = bodyNode.get("data");
                    ModelItem modelItem = new ModelItem();
                    modelItem.setId(dataNode.get("id").asText());
                    modelItem.setName(dataNode.get("name").asText());
                    modelItem.setDescription(dataNode.get("overview").asText());
                    modelItem.setAuthor(dataNode.get("author").asText());
                    modelItem.setNormalTags(objectMapper.convertValue(dataNode.get("itemClassifications"), List.class));
//                    log.info(modelItem.getNormalTags().toString());
                    modelItem.setModelType("model");
                    modelItem.setMd5(dataNode.get("md5").asText());
                    modelItem.setMdl(dataNode.get("mdl").asText());
                    modelItem.setMdlJson(ModelUtils.convertMdl(dataNode.get("mdl").asText()));
                    JsonNode MdlJson = objectMapper.readTree(objectMapper.writeValueAsString(modelItem.getMdlJson()));
                    JsonNode Mdl = MdlJson.get("mdl");
                    JsonNode states = Mdl.get("states");
                    modelItem.setData(getModelItemData(states));
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    modelItem.setUpdateTime(sdf.parse(dataNode.get("lastModifyTime").asText()));
                    modelItemDao.save(modelItem);
                }
                catch (Exception e) {
                    log.error(modelMd5);
                    log.error(e.getMessage());
                }
            }
        }
        return ResultUtils.success();
    }

    @Override
    public JsonResult saveModeltoWorkSpace(String id, String modelId, String userId) {
        try {
            Optional<ComputeModel> computeModelDB = computeModelDao.findById(modelId);
            if (!computeModelDB.isPresent()){
                return ResultUtils.error(-1,"模型不存在");
            }
            ComputeModel computeModel = computeModelDB.get();
            computeModel.getModelList().add(id);
            computeModelDao.save(computeModel);
            return ResultUtils.success("保存工具成功");
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"保存工具失败");
        }
    }

    @Override
    public JsonResult queryModelItemFuzzy(String searchText) {
        Pageable pageable = PageRequest.of(0, 20, Sort.Direction.ASC,"createTime");
        Page<ModelItem> modelItemList = modelItemDao.findAllByNameLikeIgnoreCase(searchText, pageable);
        return ResultUtils.success(modelItemList);
    }

    @Override
    public JsonResult queryResourceMethodFuzzy(String searchText) {
        Pageable pageable = PageRequest.of(0, 20, Sort.Direction.ASC, "createTime");
        Page<ModelItem> modelItemList = modelItemDao.findAllByNameLikeIgnoreCase(searchText, pageable);
        List<ModelItem> modelItems = modelItemList.getContent();
        for (ModelItem item : modelItems) {
            if (!item.getModelType().equals("method")) {
                modelItemList.getContent().remove(item);
            }
        }
        if (modelItems.size() == 0) {
            return ResultUtils.success(Collections.EMPTY_LIST);
        } else
            return ResultUtils.success(modelItems.get(0));
    }

    private Integer getHealthyMethod(int page, int pageSize) {
        Integer total = null;
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", "883ada2fc996ab9487bed7a3ba21d2f1");
        HttpEntity<String> entity = new HttpEntity<>("body", headers);
        String url = "http://" + dataServerLocation +"/renren-fast/container/method/listWithStringTag?" + "page=" + page + "&limit=" + pageSize;
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            String responseBody = responseEntity.getBody();
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                JsonNode bodyNode = objectMapper.readTree(responseBody);
                JsonNode dataNode = bodyNode.get("page");
                total = dataNode.get("totalCount").asInt();
                JsonNode content = dataNode.get("list");
                if (content.isArray()) {
                    for (int i = 0; i < content.size(); i++) {
                        JsonNode itemNode = content.get(i);
                        ModelItem modelItem = new ModelItem();
                        modelItem.setId(itemNode.get("id").asText());
                        modelItem.setName(itemNode.get("name").asText());
                        modelItem.setDescription(itemNode.get("description").asText());
                        modelItem.setAuthor("opengms@126.com");
                        modelItem.setModelType("method");
                        modelItem.setUuid(itemNode.get("uuid").asText());
                        String tags = objectMapper.writeValueAsString(itemNode.get("tagIdList"));
                        modelItem.setNormalTags(objectMapper.readValue(tags, List.class));
//                        modelItem.setNormalTags(objectMapper.convertValue(itemNode.get("tagIdList"), List.class));

                        // 这里需要解析params以获取IOParams
                        List<Param> params = new ArrayList<>();
                        List<Param> inputParams = new ArrayList<>();
                        List<Param> outputParams = new ArrayList<>();
                        for (JsonNode node : itemNode.get("params")) {
                            Param param = new Param();
                            param.setName(node.get("Name").asText());
                            ObjectMapper mapper = new ObjectMapper();

                            JsonNode flagsNode = node.get("Flags");
                            param.setFlags((List<String>) ModelUtils.extractValues(flagsNode));
                            param.setOptional(node.get("Optional").asBoolean());
                            param.setDescription(node.get("Description").asText());
                            param.setDefault_value(node.get("default_value").asText());
                            JsonNode parameterNode = node.get("parameter_type");
                            param.setParameter_type(ModelUtils.extractValues(parameterNode));
                            params.add(param);
                            if (parameterNode.has("NewFile")) {
                                outputParams.add(param);
                            } else {
                                inputParams.add(param);
                            }
                        }
                        modelItem.setParams(params);
                        modelItem.setInputParams(inputParams);
                        modelItem.setOutputParams(outputParams);

                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        modelItem.setCreateTime(sdf.parse(itemNode.get("createTime").asText()));
                        modelItemDao.save(modelItem);
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
        return total;
    }

    @Override
    public JsonResult getFromMethod() {
        Integer total = getHealthyMethod(1, 20);
        Integer totalPage = (int) Math.ceil((double) total / 20);
        for (int i = 2; i <= totalPage; i++) {
            getHealthyMethod(i, 20);
        }
        return ResultUtils.success();
    }

    public JsonResult getResourceModelList(ResourcePageDTO resourcePageDTO) {
        try{
            Pageable pageable = commonService.getResourcePageable(resourcePageDTO);
            String tagClass= resourcePageDTO.getTagClass();

            Page<ModelItem> re = modelItemDao.findAllByModelTypeAndNameLikeIgnoreCaseAndNormalTagsContainingIgnoreCase("model",resourcePageDTO.getSearchText(), resourcePageDTO.getTagNames(), pageable);
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"保存资源数据失败！");
        }
    }
    public JsonResult saveFiletoUserSpace(String folderName, List<ResourceData> resourceDataList, String userId){
        try {
            // 检查个人资源中是否已经存在该项目的文件夹
            Folder folder = folderDao.findByNameAndUserId(folderName, userId);
            Folder projectFolder = new Folder();
            List<UserData> userDataList = new ArrayList<>();
            String parentId;
            if(folder == null){
                projectFolder.setName(folderName);
                projectFolder.setUserId(userId);
                projectFolder.setParentId(userId);
                folderDao.save(projectFolder);
                parentId = projectFolder.getId();
            }else{
                parentId = folder.getId();
            }
            for (ResourceData resourceData : resourceDataList) {
                //创建dataItem实体
                UserData userData = new UserData();
                BeanUtils.copyProperties(resourceData,userData);
                userData.setParentId(parentId);
                userData.setId(IdUtil.objectId());
                String fileSizeStr = resourceData.getFileSize();
                double fileSize = Double.parseDouble(fileSizeStr);
                double fileSizeInMB = fileSize / 1048576.0;
                String fileSizeInMBStr = String.format("%.3f MB", fileSizeInMB);
                userData.setSize(fileSizeInMBStr);
                userData.setUserId(userId);
                userData.setInitial(false);
                userDataDao.save(userData);
                userDataList.add(userData);
            }
            return ResultUtils.success(userDataList);
        } catch (Exception e) {
            return ResultUtils.error(-1,"保存失败");
        }
    }

    public JsonResult getResourceModelById(String resourceModelId) {
        try {
            ModelItem modelItem = modelItemDao.findById(resourceModelId).get();
            return ResultUtils.success(modelItem);

        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"获取模型信息失败");
        }
    }

    public JsonResult resDataView(String id){
        Optional<ResourceData> byId = resourceDataDao.findById(id);
        if(!byId.isPresent()){
            return ResultUtils.error(-1,"获取数据信息失败");
        }
        ResourceData resourceData = byId.get();
        resourceData.setPageviews(resourceData.getPageviews() + 1);
        resourceDataDao.save(resourceData);
        return ResultUtils.success("数据操作成功！");
    }

    public JsonResult getResByDataView(){
        List<ResourceData> allByPageviews = resourceDataDao.findAll();
        Collections.sort(allByPageviews, (o1, o2) -> o2.getPageviews()-o1.getPageviews());
        return ResultUtils.success(allByPageviews.subList(0,6));
    }


    // 根据爬虫txt，快速导入数据资源条目
    public JsonResult saveItemDataAuto(){
        String txtPath = dataStoreDir + "/requestResult1.txt";
        ArrayList<String> strList = new ArrayList<>();
        try{
            File file=new File(txtPath);
            if(file.isFile() && file.exists()){ //判断文件是否存在
                InputStreamReader read = new InputStreamReader(
                        new FileInputStream(file),"GBK");//考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt = null;
                while((lineTxt = bufferedReader.readLine()) != null){
//                    System.out.println(lineTxt); // 一行一行的读
                    strList.add(lineTxt);
                }
                read.close();
            }else{
                System.out.println("找不到指定的文件");
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }
        for (int i = 0; i < strList.size(); i++) {
            String[] fieldList = strList.get(i).split("\t");
            ResourceData resourceItemFile=new ResourceData();
            String visualPath = "http://nnu.geodata.cn/data/datadetails.html?dataguid=" + fieldList[0] + "&docid=" + fieldList[2];
            String name = fieldList[1];
            String fileSize = fieldList[3];
            String thumbnailPath = "http://img.data.ac.cn/" + fieldList[4];
            String problemTags;
            if(fieldList.length <= 5){
                problemTags = "";
            }else {
                problemTags = fieldList[5];
            }
            String normalTags;
            if(fieldList.length <= 6){
                normalTags = "";
            } else {
                normalTags = fieldList[6];
            }
            if(fieldList.length == 8){
                normalTags = normalTags + "," + fieldList[7];
            }
            resourceItemFile.setName(name);
            resourceItemFile.setType("data");
            resourceItemFile.setFileSize(fileSize);
            resourceItemFile.setDescription(name);
            resourceItemFile.setFileWebAddress(visualPath);
            resourceItemFile.setImgWebAddress(thumbnailPath);
            resourceItemFile.setUserEmail("temp@xx.com");
            resourceItemFile.setProblemTags(problemTags);
            resourceItemFile.setNormalTags(normalTags);
            resourceDataDao.save(resourceItemFile);
        }
        return ResultUtils.success(strList);
    }

    @Override
    public JsonResult getPublicUserDataList(ResourcePageDTO resourcePageDTO) {
        try{
            Pageable pageable = commonService.getResourcePageable(resourcePageDTO);
            String tagClass= resourcePageDTO.getTagClass();

            if(tagClass.equals("problemTags")){
                Page<UserData> re = userDataDao.findAllByNameLikeIgnoreCaseAndProblemTagsLikeIgnoreCaseAndPublicBooleanIsTrueAndTypeIsNotAndInitialIsTrue(resourcePageDTO.getSearchText(), resourcePageDTO.getTagName(),pageable,true, "folder", true);
                return ResultUtils.success(re);
            }else if(tagClass.equals("normalTags")){
                Page<UserData> re = userDataDao.findAllByNameLikeIgnoreCaseAndNormalTagsLikeIgnoreCaseAndPublicBooleanIsTrueAndTypeIsNotAndInitialIsTrue(resourcePageDTO.getSearchText(), resourcePageDTO.getTagName(),pageable,true, "folder", true);
                return ResultUtils.success(re);
            }else {
                return ResultUtils.error(-1,"数据类别不正确，problemTags或normalTags");
            }
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"获取资源数据失败！");
        }
    }

    @Override
    public JsonResult saveUserFiletoUserSpace(String folderName, List<UserData> dataList, String userId) {
        try {
            // 检查个人资源中是否已经存在该项目的文件夹
            Folder folder = folderDao.findByNameAndUserId(folderName, userId);
            Folder projectFolder = new Folder();
            List<UserData> userDataList = new ArrayList<>();
            String parentId;
            if(folder == null){
                projectFolder.setName(folderName);
                projectFolder.setUserId(userId);
                projectFolder.setParentId(userId);
                folderDao.save(projectFolder);
                parentId = projectFolder.getId();
            }else{
                parentId = folder.getId();
            }
            for (UserData data : dataList) {
                //创建dataItem实体
                UserData userData = new UserData();
                BeanUtils.copyProperties(data,userData);
                userData.setId(IdUtil.objectId());
                userData.setParentId(parentId);
                userData.setUserId(userId);
                userData.setInitial(false);
                userDataDao.save(userData);
                userDataList.add(userData);
            }
            return ResultUtils.success(userDataList);
        } catch (Exception e) {
            return ResultUtils.error(-1,"保存失败");
        }
    }
}
